<?php

namespace Piwik\Plugins\AdsPlace;

use Exception;
use Piwik\API\Request;
use Piwik\API\ResponseBuilder;
use Piwik\Common;
use Piwik\DataTable\Renderer\Json;
use Piwik\Date;
use Piwik\Nonce;
use Piwik\Notification;
use Piwik\Option;
use Piwik\Piwik;
use Piwik\Plugin;
use Piwik\Plugin\ControllerAdmin;
use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
use Piwik\Plugins\Login\PasswordVerifier;
use Piwik\Plugins\TagManager\Validators\TriggerIds;
use Piwik\Plugins\UsersManager\API as APIUsersManager;
use Piwik\SettingsPiwik;
use Piwik\Site;
use Piwik\Tracker\IgnoreCookie;
use Piwik\Translation\Translator;
use Piwik\Url;
use Piwik\Validators\BaseValidator;
use Piwik\Validators\CharacterLength;
use Piwik\Validators\NotEmpty;
use Piwik\View;
use Piwik\Session\SessionInitializer;
use Piwik\Plugins\AdsPlace\Lib\RedisAdapter;
use Piwik\Plugins\AdsPlace\Model;


class Controller extends ControllerAdmin {

    /**
     * @var Translator
     */
    private $translator;
    protected $_track_siteid = 53;

    public function __construct(Translator $translator) {
        parent::__construct();

        $this->translator = $translator;
    }
   /**
    * 提供给app端调用信息流 的广告位 
    */
    public function adstream()
    {
        $model = new Model();
        $ownerid = Common::getRequestVar('ownerid',0);
        
        $ret = $model->getPlaceByPlaceType( 4, $ownerid );  
        Json::sendHeaderJSON();
        return json_encode(['data'=>$ret, 'errorCode'=>0]);
    }
    /**
     * 返回某个广告位显示的广告投放物料信息
     * @param type $idpalce
     */   
    public function adstreamshow( ){
        $idplace = Common::getRequestVar('idplace',0);
        $ret = [];
        if($idplace > 0){
            $ret = $this->_adplace_show_medias($idplace);
            $ret['medias']['content'] = json_decode($ret['medias']['content'], true);
        }
        Json::sendHeaderJSON();
        return json_encode(['data'=>$ret, 'errorCode'=>0]);
    }

    /**
     * 公用的模板变量
     * @param type $view
     */
    private function _set_view_var($view) {
        $this->setBasicVariablesView($view);
        $view->adminMenu = \Piwik\Menu\MenuPlace::getInstance()->getMenu();
    }

    public function index() {
        $view = new View("@AdsPlace/index");
        $this->_set_view_var($view);
        return $view->render();
    }

    /**
     * report 整体报告页面
     */
    public function report() {
        $view = new View("@AdsPlace/report");

        $this->_set_view_var($view);

        return $view->render();
    }

    /**
     * 投放报告
     * @return type
     */
    public function adverteReport() {
        $view = new View("@AdsPlace/report_adverte");
        /*查询某个广告投放计划的统计*/
        $view->idadverte = Common::getRequestVar('idadverte',0);
        $this->_set_view_var($view);
        return $view->render();
    }

    /**
     * 广告物料报告
     */
    public function mediasReport() {
        $view = new View("@AdsPlace/report_medias");

        $view->idmedias = Common::getRequestVar('idmedias',0);
        
        $this->_set_view_var($view);
        return $view->render();
    }

    /**
     * 投放广告
     */
    public function setplace() {
        $view = new View("@AdsPlace/setplace");

        $this->_set_view_var($view);
        return $view->render();
    }

    /**
     * 媒体站点
     */
    public function siteapp() {
        $view = new View("@AdsPlace/siteapp");

        $this->_set_view_var($view);
        return $view->render();
    }

    //     广告素材管理
    public function medias() {
        $view = new View("@AdsPlace/medias");

        $this->_set_view_var($view);
        return $view->render();
    }
    /**
     * 检测redis、mysql、pgsql是否正常运行。
     */
    public function detection()
    {
        /**
         * 通过post  提交参数检测 redis、mysql、pgsql运行状态；
         */
        
        $testtype =  Common::getRequestVar('testtype', '',null, $_POST);
        if($testtype == 'redis'){
            $redis   =  Common::getRequestVar('redisStr','');
            $adapter  =  new RedisAdapter(  );           
            try{           
                 $adapter->connectReis($redis);            
                 $response = $adapter->ping();
                 return $response;

            } catch (Exception $ex) {
                return 0;
            }
            return 0 ;
        }
        //检测mysql 连接
        if($testtype == 'mysql'){
            $ipstr   =  Common::getRequestVar('mysqlIP','127.0.0.1');
            $user = Common::getRequestVar('mysqlUser','');
            $pass = Common::getRequestVar('mysqlPass','');       
            $ipstr = explode("@", $ipstr);
            $conn = mysqli_connect($ipstr[0], $user, $pass, "", $ipstr[1]);          
            if(!$conn){
                return 0;
            }else{
                mysqli_close($conn);
                return 1;
            }
        }
        //检测pgsql 
        if($testtype =='pgsql'){
            $ipstr   =  Common::getRequestVar('PgsqlIP','127.0.0.1');
            $user = Common::getRequestVar('PgsqlUser','');
            $pass = Common::getRequestVar('PgsqlPass','');       
            $ipstr = explode("@", $ipstr);
            $port = isset($ipstr[1]) ? $ipstr[1] : 5432;
            try{
                $conn =  new \PDO("pgsql:host={$ipstr[0]};port={$port};user={$user};password={$pass}");
                return 1;   
            } catch (PDOException $ex) {
                 return 0;
            }
           
        }
        /* 以下是get请求显示 检测页面表单设置等。*/
        $view = new View("@AdsPlace/xfdetection");

        $this->_set_view_var($view);
        return $view->render();     
    }
    /**
     * 默认ping mysql 的默认ip和端口号，可以指定某个ip 和端口号 进行ping检测。
     * 返回ping的耗时。如果ping失败返回-1.
     * @return type
     */
    public function ping(){
        $testtype =  Common::getRequestVar('testtype', 'mysql');
        $ipstr =  Common::getRequestVar('ipstr','127.0.0.1');
        $ipstr2 = explode("@", $ipstr);
        $ports = ['redis'=>6379, 'mysql'=> 3306, 'pgsql'=> 5432];
        if(!isset($ipstr2[1])) {
            $port = $ports[$testtype];
        }else{
            $port = $ipstr2[1];
        }
        $ip = $ipstr2[0];
        return $this->_pingDomain($ip, $port);
    }

    /**
     * 通过fsockopen 检测ip上的某个端口是否可以连接
     * @param type $domain
     * @param type $port
     * @return type >0 表示连接耗时 否则连接失败。
     */
    private function _pingDomain($domain , $port){
          
            $file      = fsockopen ($domain, $port, $errno, $errstr, 30);
            
            $status    = 0;
            if (!$file) {
                $status = 0;  // Site is down
            }else {
                fclose($file);
                $status = 1;                
            }
            return $status;
   }
    //影音先锋 广告投放 xfjson
    public function xfjson() {
        //指定只有xfplay这个账号可以设置 本页面参数
        if (Piwik::getCurrentUserLogin() !== 'xfplay') {
            throw new \Piwik\NoAccessException(Piwik::translate('General_YouMustBeLoggedIn'));
        }

        $view = new View("@AdsPlace/xfjson");

        $this->_set_view_var($view);
        return $view->render();
    }

    /* 预览广告物料素材 */

    public function preview() {
        $view = new View("@AdsPlace/preview");
        $view->mediasId = Common::getRequestVar('mediasId', 0);

        $this->_set_view_var($view);
        return $view->render();
    }

    /**
     * 提供给 外部访问获取数据
     * js 库 PlaceAPI.getmedias 方法
     * 获取物料信息
     */
    public function getmedias() {
        $mediasId = Common::getRequestVar('idmedias', 0);
        // 通过controller 方法调用内部API 可以不需要登录；
        $report = \Piwik\API\Request::processRequest('AdsPlace.dispatch', array(
                    'enews' => 'getMedias',
                    'idmedias' => $mediasId,
                        //'date'   => $date,
        ));
        Json::sendHeaderJSON();
        return json_encode($report);
    }
    /**
     * 获取一个广告位 当前应该显示 哪个投放方案里面的某个物料
     *  已经废弛，保留作为 最初版本以供查看。
     * 目的是把这个功能 实现数据和模板分离，
     * 分解成两部 _adplace_show_medias（）专门获取数据，showad 显示给模板
     * 其他方法 还可以调用 _adplace_show_medias（），获取广告投放数据
     */
    private function _adplace_show_medias( $idplace)
    {
        $model = new Model();
        // 获取广告位 数据；
        $adplace  = $model->getOnePlace($idplace);
        /* 获取此广告位 投放的广告计划 */
        $advertes = $model->getPlaceAdvertes($adplace['id']);

        $last = [];
        $priority = []; //存储零时优先级方案
        $weight = [];
        /* 通过判断 starttime 和endtime，优先级 等投放条件，获得当前采用哪个投放方案 */
        if (!empty($advertes)) {
            foreach ($advertes as $key => $adv) {
                //未开始的投放计划去掉
               if( $adv['proid']==2){ /*按天投放的情况*/
                    $nowstr = date('Y-m-d');                
                    if(!empty($adv['proidRows'])){
                        if(strpos(','.$adv['proidRows'].',', $nowstr) !== FALSE ){
                             unset($advertes[$key]);
                        }
                    }
               }else{/*设置过时间段开始和结束时间*/
                    $now = time();
                    if (strtotime($adv['startday'] . ' ' . $adv['starttime']) > $now) {
                        unset($advertes[$key]);
                    }
                    //到期的投放计划去掉
                    if ($adv['hasendtime'] && ( strtotime($adv['endday'] . ' ' . $adv['endtime']) < $now)) {
                        unset($advertes[$key]);
                    }
               }
                //按优先级 的类型 分组投放方案
                $priority[$adv['priority']][] = $adv;
               
            }
        } 
        if(!empty($priority))   {
            //这里还要继续计算优先级和 权重都设置了的           
            if(!empty($priority[4])){ //先看补余的投放
                $last = $priority[4];
            }
            if(!empty($priority[3])){ // 标准投放
                $last = $priority[3];
            }
            if(!empty($priority[2])){ //优先的投放
                $last = $priority[2];
            } 
            if(!empty($priority[1])){ //独占的投放
                $last = $priority[1];
            } 
            //暂时未实现，直接采用优先级第一个的
           //  $weight = $priority[0];
        }
        if (!empty($last)) {
            //当前优先级类型里面有多个方案，还需要判断他们的权重
            if (count($last) > 1) {             
                $tmp = [];
                $wleve = [];
                for ($i = 0; $i < count($last); $i++) {               
                    if($last[$i]['weight']>0){
                        $n = intval( $last[$i]['weightLeve']);
                        //记录方案的权重值
                        array_push($wleve, $n);
                        //记录广告方案的在数组中的位置
                        $tmp[$i] = $n;
                    }
                }
                if(count($wleve)>1){
                    //按权重分配显示概率
                    $min = min($wleve);
                    $max = max($wleve);
                    $index = mt_rand(1,  intval($min+ $max));
                    //分配给优先级小的
                    foreach($tmp as $key => $n ){                      
                        if( ($n > $min) && ($n  >= $index ) ) {
                            $weight = $last[$key];  
                        }                          
                    }
                    //分配给优先级大的。
                    if(empty($weight)){
                      foreach($tmp as $key => $n ){
                         if($n == $min ) { //显示优先权重高的
                             $weight = $last[$key];                             
                         } 
                      }
                    }
                }else{
                    //这些方案都没有设置权重，默认就随机显示
                    $index = mt_rand(1, count($last)) - 1;
                    $weight = $last[$index];
                }
                
            } else {
                $weight = $last[0];
            }
        }
        /**
         * 下面计算获取到物料，如果物料数量大于1
         * 需要轮流显示物料 
         */
        // 从当前的投放方案 中获取投放方案设置的物料
        $mids = explode(",", $weight['medias']);
        // 默认显示物料
        $index = 0;
        if (count($mids) > 1) {
            //随机 获取其中一个，这里应该有更加高级的算法实现均衡权重等显示物料
            $index = mt_rand(1, count($mids)) - 1;
        }
        //设置当前投放的物料ID      
        $mediasId = $mids[$index];
        //获取物料数据
        $medias = $model->getMediasById( $mediasId );
        
        return [
            'idplace'           =>  $idplace,
            'adverte'           =>  $weight,
            'medias'            =>  $medias,
            'mediasId'          =>  $mediasId,
            'caculateMethod'    => $weight['caculateMethod'],
            'perPrice'          => $weight['perPrice'],
            'disabled'          => $adplace['disabled'],
            //广告位统计参数
            'impContentName'    =>   "adplace{$idplace}name",
            'impContentPiece'   =>   "tfadverte" . $weight['id'] . "name", 
            'impContentTarget'  =>   $weight['adverteName'], 
            //广告位的物料统计
            'intContentName'    =>  "tfadverte" . $weight['id'] . "name",
            'intConentPiece'    =>   "medias" . $medias['id'] . "name",
            'intContentTarget'  =>   $medias['linkurl'],
            'tracker_server_url' =>  Url::getCurrentScheme() . '://' . Url::getCurrentHost(), 
            'trackerSiteId'      =>  $this->_track_siteid,/* !empty($adplace['ownerid']) ?  $adplace['ownerid'] :$this->_track_siteid, */    
        ];
    }
  /** 
     * 目的是把这个功能 实现数据和模板分离，
     * 分解成两部 _adplace_show_medias（）专门获取数据，showad 显示给模板
     * 其他方法 还可以调用 _adplace_show_medias（），获取广告投放数据
     * 展示输出广告位的信息      * 
     */
    public function showad()
    {
        $view = new View("@AdsPlace/showad_es5");
        $view->idplace = Common::getRequestVar('idplace', 13);
        $view->cs = Common::getRequestVar('cs', '');

        $view->referer = Common::getRequestVar('referer', '');  
        $ret = $this->_adplace_show_medias($view->idplace);
     
        $weight = $ret['adverte'];
        /*当前展示的物料*/
        //$ret['medias']['content'] = json_decode($ret['medias']['content'], true);
        $view->medias =  $ret['medias'];
        //设置当前投放的物料ID      
        $view->mediasId = $ret['mediasId'];
        $view->caculateMethod = $ret['caculateMethod'];
        $view->perPrice = $ret['perPrice'];
        $view->disabled = $ret['disabled'];
        //}
        //广告位统计参数
        $view->impContentName = $ret['impContentName']; //"adplace" . $view->idplace . "name";
        $view->impContentPiece = $ret['impContentPiece']; //"tfadverte" . $weight['id'] . "name";
        $view->impContentTarget = $ret['impContentTarget']; //$weight['adverteName'];
        //广告位的物料统计
        $view->intContentName = $ret['intContentName']; //"tfadverte" . $weight['id'] . "name";
        $view->intConentPiece = $ret['intConentPiece']; //"medias" . $medias['id'] . "name";
        $view->intContentTarget = $ret['intContentTarget']; //$medias['linkurl'];
        // Common::getRequestVar('mediasId',0);
        $view->tracker_server_url = $ret['tracker_server_url']; //Url::getCurrentScheme() . '://' . Url::getCurrentHost();
        //改变这个idSIte变量，把广告位等统计记入哪个站点将改变，默认49.
        $view->trackerSiteId = $ret['trackerSiteId']; //$this->_track_siteid;

        // 通过这个设置模板变量后，不验证登陆状态，即不登录也能访问到这个方法
        $this->setBasicVariablesNoneAdminView($view);
        $view->setXFrameOptions('allow');
        return $view->render();
    }

    /**
     * 已经废弛，保留作为 最初版本以供查看。
     * 目的是把这个功能 实现数据和模板分离，
     * 分解成两部 _adplace_show_medias（）专门获取数据，showad 显示给模板
     * 其他方法 还可以调用 _adplace_show_medias（），获取广告投放数据
     * 展示输出广告位的信息      * 
     */
    public function showad2() {
        $view = new View("@AdsPlace/showad");
        $view->idplace = Common::getRequestVar('idplace', 13);

        $view->referer = Common::getRequestVar('referer', '');

        $model = new Model();
        // 获取广告位 数据；
        $adplace = $model->getOnePlace($view->idplace);

        /* 获取此广告位 投放的广告计划 */
        $advertes = $model->getPlaceAdvertes($adplace['id']);

        $last = [];
        $priority = []; //存储零时优先级方案
        $weight = [];
        /* 通过判断 starttime 和endtime，优先级 等投放条件，获得当前采用哪个投放方案 */
        if (!empty($advertes)) {
            foreach ($advertes as $key => $adv) {
                //未开始的投放计划去掉
                $now = time();
                if (strtotime($adv['startday'] . ' ' . $adv['starttime']) > $now) {
                    unset($advertes[$key]);
                }
                //到期的投放计划去掉
                if ($adv['hasendtime'] && ( strtotime($adv['endday'] . ' ' . $adv['endtime']) < $now)) {
                    unset($advertes[$key]);
                }
                //按优先级 的类型 分组投放方案
                $priority[$adv['priority']][] = $adv;
               
            }
        }
 
        if(!empty($priority))   {
            //这里还要继续计算优先级和 权重都设置了的           
            if(!empty($priority[4])){ //先看补余的投放
                $last = $priority[4];
            }
            if(!empty($priority[3])){ // 标准投放
                $last = $priority[3];
            }
            if(!empty($priority[2])){ //优先的投放
                $last = $priority[2];
            } 
            if(!empty($priority[1])){ //独占的投放
                $last = $priority[1];
            } 
            //暂时未实现，直接采用优先级第一个的
           //  $weight = $priority[0];
        }
        if (!empty($last)) {
            //当前优先级类型里面有多个方案，还需要判断他们的权重
            if (count($last) > 1) {             
                $tmp = [];
                $wleve = [];
                for ($i = 0; $i < count($last); $i++) {               
                    if($last[$i]['weight']>0){
                        $n = intval( $last[$i]['weightLeve']);
                        //记录方案的权重值
                        array_push($wleve, $n);
                        //记录广告方案的在数组中的位置
                        $tmp[$i] = $n;
                    }
                }
                if(count($wleve)>1){
                    //按权重分配显示概率
                    $min = min($wleve);
                    $max = max($wleve);
                    $index = mt_rand(1,  intval($min+ $max));
                    //分配给优先级小的
                    foreach($tmp as $key => $n ){                      
                        if( ($n > $min) && ($n  >= $index ) ) {
                            $weight = $last[$key];  
                        }                          
                    }
                    //分配给优先级大的。
                    if(empty($weight)){
                      foreach($tmp as $key => $n ){
                         if($n == $min ) { //显示优先权重高的
                             $weight = $last[$key];                             
                         } 
                      }
                    }
                }else{
                    //这些方案都没有设置权重，默认就随机显示
                    $index = mt_rand(1, count($last)) - 1;
                    $weight = $last[$index];
                }
                
            } else {
                $weight = $last[0];
            }
        }
        /**
         * 下面计算获取到物料，如果物料数量大于1
         * 需要轮流显示物料 
         */
        // 从当前的投放方案 中获取投放方案设置的物料
        $mids = explode(",", $weight['medias']);
        // 默认显示物料
        $index = 0;
        if (count($mids) > 1) {
            //随机 获取其中一个，这里应该有更加高级的算法实现均衡权重等显示物料
            $index = mt_rand(1, count($mids)) - 1;
        }
        //设置当前投放的物料ID      
        $view->mediasId = $mids[$index];
        //获取物料数据
        $meidas = $model->getMediasById($view->mediasId);
        //广告计划的计费方式用于统计千展示次数和 点击数
        //if($weight['caculateMethod'] ==2){
        //计费方式是cpm 千次展示多少钱
        $view->caculateMethod = $weight['caculateMethod'];
        $view->perPrice = $weight['perPrice'];
        //}
        //广告位统计参数
        $view->impContentName =  "adplace" . $view->idplace . "name";
        $view->impContentPiece = "tfadverte" . $weight['id'] . "name";
        $view->impContentTarget = $weight['adverteName'];
        //广告位的物料统计
        $view->intContentName = "tfadverte" . $weight['id'] . "name";
        $view->intConentPiece = "medias" . $meidas['id'] . "name";
        $view->intContentTarget = $meidas['linkurl'];
        // Common::getRequestVar('mediasId',0);
        $view->tracker_server_url = Url::getCurrentScheme() . '://' . Url::getCurrentHost();
        //改变这个idSIte变量，把广告位等统计记入哪个站点将改变，默认49.
        $view->trackerSiteId = $this->_track_siteid;
        // 通过这个设置模板变量后，不验证登陆状态，即不登录也能访问到这个方法
        $this->setBasicVariablesNoneAdminView($view);
        $view->setXFrameOptions('allow');
        return $view->render();
    }

    /**
     * 通过 format 获取 contentName 的统计内容名称 contentName 
     * 广告位是  adplace%dname  = adplace[1,2,3,id……]name
     * 投放方案是  tfadverte%dname = tfadverte[1,2,3,id……]name
     * @param type $format
     * @return type
     */
    private function _get_adplace_segment_reg() {
        $model = new Model();
        $format = "adplace%dname";
        $segment = [];
        $filter  = [];
        $id = Common::getRequestVar('adplaceId', 0);
         $currentUserLogin = Common::getRequestVar('currentUserLogin',  Piwik::getCurrentUserLogin() );
        if ($id > 1) {
            $items = $model->getPlaceIdsById($id);
        } else {
            $items = $model->getPlaceIdsByCreatorLogin( $currentUserLogin );
        }
        foreach ($items as $key => $val) {
            array_push($segment, "contentName==" . sprintf($format, $val['id']));
            array_push($filter, sprintf($format, $val['id']));
        }
        //查询api接口的segment 参数和 filter_pattern = 
        return ['segment' => $segment, 'filter' => $filter, 'items' => $items,'currentUserLogin'=> $currentUserLogin];
    }

    /**
     * 广告投放的 segment 和 filter_pattern
     * @return type
     */
    private function _get_adverte_segment_reg() {
        $model = new Model();
        $format = "tfadverte%dname";
        $segment = [];
        $filter = [];
        $id = Common::getRequestVar('adverteId', 0);
        $currentUserLogin = Common::getRequestVar('currentUserLogin',  Piwik::getCurrentUserLogin() );
        if ($id > 1) {
            $items = $model->getAdvertesById($id);
        } else {
            $items = $model->getAdvertesByCreatorLogin( $currentUserLogin);
        }
        foreach ($items as $key => $val) {
            array_push($segment, "contentName==" . sprintf($format, $val['id']));
            array_push($filter, sprintf($format, $val['id']));
        }
        //查询api接口的segment 参数和 filter_pattern = 
        return ['segment' => $segment, 'filter' => $filter, 'items' => $items,'currentUserLogin'=> $currentUserLogin];
    }

    /**
     * 广告物料的 segment 和 filter_pattern
     * @return type
     */
    private function _get_medias_segment_reg() {
        $model = new Model();
        $format = "medias%dname";
        $segment = [];
        $filter = [];
        $id = Common::getRequestVar('mediasId', 0);
        $currentUserLogin = Common::getRequestVar('currentUserLogin',  Piwik::getCurrentUserLogin() );
        if ($id > 1) {
            $items = $model->getMediasArrayById($id);
        } else {
            $items = $model->getMediasByCreatorLogin($currentUserLogin);
        }
        foreach ($items as $key => $val) {
            array_push($segment, "contentPiece==" . sprintf($format, $val['id']));
            array_push($filter, sprintf($format, $val['id']));
        }
        //查询api接口的segment 参数和 filter_pattern = 
        return ['segment' => $segment, 'filter' => $filter, 'items' => $items, 'currentUserLogin'=> $currentUserLogin];
    }

    /**
     * 
     * @param type $startdate
     * @param type $nowdate
     * @param type $period = day
     * @return type
     */
    private function _getContentNamesData($format, $startdate, $nowdate, $period = 'day') {
        /**
         * 获取所有广告位的统计信息
         * https://demo.matomo.cloud/?module=API
         * &method=Contents.getContentNames&idSite=1&period=day
         * &date=yesterday&format=JSON&token_auth=anonymous
         */
        if (count($format['segment']) == 1) {
            array_push($format['segment'], $format['segment'][0]);
            //增加一个重复的如果只有一个 值，bug修复
        }
        $params = [
            'idSite' => $this->_track_siteid,
            'date' => "{$startdate},{$nowdate}",
            // 'date'=> "2021-12-09,2021-12-09",
            'segment' => implode(",", $format['segment']) . "",
            // 'segment'=> 'contentName==adplace13name,contentName==adplace9name',
            //segment = "contentName==adplace_13,contentName==adplace_15",
            'period' => $period,
            // day 如果date= 一个时间段，那么按天返回时间段内每天的数据数组           
            'format' => 'json',
            'filter_pattern' => '(' . implode("|", $format['filter']) . ')',
        ];

        $ret = Request::processRequest('Contents.getContentNames', $params, $default = []);
        // 返回查询结果和 广告位或者 投放
        return $ret;
    }

    private function _getContentPiecesData($format, $startdate, $nowdate, $period = 'day') {

        if (count($format['segment']) == 1) {
            array_push($format['segment'], $format['segment'][0]);
            //增加一个重复的如果只有一个 值，bug修复
        }
        $params = [
            'idSite' => $this->_track_siteid,
            'date' => "{$startdate},{$nowdate}",
            'segment' => implode(",", $format['segment']) . "",
            'period' => $period,
            'format' => 'json',
            'filter_pattern' => '(' . implode("|", $format['filter']) . ')',
        ];

        $ret = Request::processRequest('Contents.getContentPieces', $params, $default = []);
        // 返回查询结果和 广告位或者 投放
        return $ret;
    }

    public function reportAdsPlaceRange() {
        $startdate      = Common::getRequestVar('startdate', date('Y-m-d'));
        $nowdate        = Common::getRequestVar('nowdate', date('Y-m-d'));
        $days           = Common::getRequestVar('days', 1);
        $type           = Common::getRequestVar('type', 'adplace');
        $period = 'day';
        $label_pre = '日';
        if ($days > 7 && $days < 61) {
            $period         = 'week';
            $label_pre      = '周';
        }
        if ($days > 60 && $days < 210) {
            $period         = 'month';
            $label_pre      = '月';
        }
        if ($days > 210) {
            $period         = 'year';
            $label_pre      = '年';
        }
        if ($type == 'adplace') {
            $format     = $this->_get_adplace_segment_reg();
        } elseif ($type == 'medias') {
            //获取媒体列表和 下面查询接口的segment条件
            $format = $this->_get_medias_segment_reg();
        } else {
            $format = $this->_get_adverte_segment_reg();
        }

        if ($type == 'medias') {
            /* 统计 物料的时候  通过 contentPieces 接口获取统计数据 */
            $ret = $this->_getContentPiecesData($format, $startdate, $nowdate, $period);
        } else {
            $ret = $this->_getContentNamesData($format, $startdate, $nowdate, $period);
        }

        //把获取到的json数据 解析得到数组
        $dataTable = json_decode($ret, true);
        $tablelist = $this->_caculate_days($dataTable, $label_pre);

        return json_encode(($tablelist));
    }

    /**
     * 广告物料的 总统计数据
     */
    public function mediasOverview() {
        $startdate = Common::getRequestVar('startdate', date('Y-m-d', strtotime("-7 day")));
        $nowdate = Common::getRequestVar('nowdate', date('Y-m-d'));

        $format = $this->_get_medias_segment_reg();

        $ret = $this->_getContentPiecesData($format, $startdate, $nowdate);

        //把获取到的json数据 解析得到数组
        $dataTable = json_decode($ret, true);

        $total = $this->_caculate_total($dataTable);
        //计算每天的数据
        //计算 总收入
        $c = $this->_caculate_goals_revenue($format, $startdate, $nowdate, 'medias');
        //所有投放物料的 收入
        $total['nb_visits'] = $c['revenue'];
        // 投放计划的汇总
        foreach ($format['items'] as $key => $val) {
            $format['labels'][$val['id']] = $val['name'];
        }
        $tablelist = $this->_caculte_by_label($format, $dataTable);
        // 计算每个物料的 cpc
        foreach ($tablelist as $key => $val) {
            //把每个广告投放 的 按点击cpc 统计的费用赋值给cpc；
            if( isset($c['ids'][$val['id']]) ){
                $tablelist[$key]['cpc'] = round($c['ids'][$val['id']] * 100) / 100;
            }else{
                $tablelist[$key]['cpc'] = 0;
            }
        }
        return json_encode([
            'total'         => $total,
            'items'         => $format['items'],
            'tablelist'     => $tablelist,
            'currentUserLogin'=> $format['currentUserLogin']
        ]);
    }

    /**
     * 投放方案的 总统计数据
     */
    public function adverteOverview() {
        $startdate = Common::getRequestVar('startdate', date('Y-m-d', strtotime("-7 day")));
        $nowdate = Common::getRequestVar('nowdate', date('Y-m-d'));

        $format = $this->_get_adverte_segment_reg();

        $ret = $this->_getContentNamesData($format, $startdate, $nowdate);

        //把获取到的json数据 解析得到数组
        $dataTable = json_decode($ret, true);

        $total = $this->_caculate_total($dataTable);
        //计算 总收入
        $c = $this->_caculate_goals_revenue($format, $startdate, $nowdate, 'adverte');
        $total['nb_visits'] = $c['revenue'];
        //计算每天的数据
        // 投放计划的汇总
        foreach ($format['items'] as $key => $val) {
            $format['labels'][$val['id']] = $val['adverteName'];
        }
        $tablelist = $this->_caculte_by_label($format, $dataTable);
        foreach ($tablelist as $key => $val) {
            //把每个广告投放 的 按点击cpc 统计的费用赋值给cpc；
            if(isset($tablelist[$key]['cpc']) && isset($c['ids'][$val['id']])){
                $tablelist[$key]['cpc'] = round($c['ids'][$val['id']] * 100) / 100;
            }else{
                $tablelist[$key]['cpc'] = 0 ;
            }
            
        }

        return json_encode([
            'total'         => $total,
            'items'         => $format['items'],
            'tablelist'     => $tablelist,
            'currentUserLogin'=> $format['currentUserLogin']
        ]);
    }

    /**
     * 获取当前账号的全部广告位 统计数据
     */
    public function reportOverview() {
        // 把ContentNames 数据按天返回
        $startdate = Common::getRequestVar('startdate', date('Y-m-d', strtotime("-1 day")));
        $nowdate = Common::getRequestVar('nowdate', date('Y-m-d'));
        //$period = Common::getRequestVar('period','day'); 
        $format = $this->_get_adplace_segment_reg();
        // period= day 返回的数据 是 ["2021-12-02":[{},{}……],"2021-12-03":[] ……]
        $ret = $this->_getContentNamesData($format, $startdate, $nowdate);

        //把获取到的json数据 解析得到数组
        $dataTable = json_decode($ret, true);

        $total = $this->_caculate_total($dataTable);
        //计算每天的数据
        $tablelist = $this->_caculate_days($dataTable);

        /**
         * 输出汇总 展现量 浏览量 点击量，total
         * tablelist 是 表格数据
         * items 是搜索的下拉select 组件options数据
         */
        $c = $this->_caculate_goals_revenue($format, $startdate, $nowdate);
        $total['nb_visits'] = $c['revenue'];
        /* 把table显示的每天的ecpm和cpc 数据 */
        foreach ($tablelist as $key => $table) {
            $tablelist[$key]['cpc'] = $c['days'][$table['day']];
        }
        //把总的按点击量得到的总收入复制给这个统计；
        return json_encode([
            'total'         => $total,
            'tablelist'     => array_reverse($tablelist),
            'items'         => $format['items'],
            'currentUserLogin'=> $format['currentUserLogin']
        ]);
    }

    /**
     * 获取收入 通过Goals 模块的接口获取 
     * 返回对应的type 类型的 每日 下各个统计类目的 数据列表
     * {
     *  "2021-12-02":[{lable: "cadplace12name", revenue: 2.3 …… }]
     *  ……
     * }
     *  返回的数据是 接口Goals.getItemsCategory，Goals.getItemsName，或者 Goals.getItemsSku
     *  的按对应类型 返回 sku，name，category 的电商统计数据，详细查看 matomo的电商接口
     *  $format 的items 主要是 广告位列表，广告投放计划，广告物料 三种列表数据
     */
    private function _caculate_goals_revenue($format, $startdate, $nowdate, $type = 'adplace') {
        $pattern = [];
        $api = 'Goals.getItemsCategory';
        foreach ($format['items'] as $key => $val) {
            if ($type == 'adplace') {
                array_push($pattern, sprintf("cadplace%dname", $val['id']));
                $api = 'Goals.getItemsCategory';
            }
            if ($type == 'adverte') {
                array_push($pattern, sprintf("ntfadverte%dname", $val['id']));
                $api = 'Goals.getItemsName';
            }
            if ($type == 'medias') {
                array_push($pattern, sprintf("skumedias%dname", $val['id']));
                $api = 'Goals.getItemsSku';
            }
        }
        $params = [
            'idSite' => $this->_track_siteid,
            'date' => "{$startdate},{$nowdate}",
            // 'segment' => implode(",", $format['segment'])."",                   
            'period' => 'day',
            'format' => 'json',
            'filter_pattern' => '(' . implode("|", $pattern) . ')',
        ];
        $total = 0;
        $days = [];
        $json = Request::processRequest($api, $params, $default = []);
        $ret = json_decode($json, true);
        $ids = [];

        foreach ($ret as $key => $val) {
            $tmp = 0;
            foreach ($val as $k => $v) {
                $tmp = $tmp + $v['revenue'];
                //按label中包含的 id 统计 用于统计投放方案和物料的
                preg_match('/\d+/', $v['label'], $r);
                if (isset($ids[$r[0]])) {
                    $ids[$r[0]] = $ids[$r[0]] + floatval($v['revenue']);
                } else {
                    $ids[$r[0]] = floatval($v['revenue']);
                }
            }
            //$tmp = round($tmp * 100 ) /100;
            $total = $total + $tmp;
            //按日期汇总
            $days[$key] = $tmp;
        }
        $func = function($value) {
            return round($value * 100) / 100;
        };
        return ['revenue' => round($total * 100) / 100, 'days' => array_map($func, $days), 'ids' => array_map($func, $ids)];
    }

    private function _caculate_total($dataTable) {
        $total = [
            'label' => '',
            'nb_visits' => 0, //访问量 
            'nb_uniq_visitors' => 0,
            'sum_daily_nb_uniq_visitors' => 0, //唯一访问量
            'nb_impressions' => 0, // 展示量
            'nb_interactions' => 0, // 点击量
            'interaction_rate' => 0, //点击率
            'ecpm' => 0,
            'cpc' => 0,
        ];
        //计算汇总的数据
        foreach ($dataTable as $key => $r) {
            if (!empty($r)) {
                foreach ($r as $k => $val) {
                    $total['nb_visits'] += $val['nb_visits'];
                    $total['nb_uniq_visitors'] += $val['nb_uniq_visitors'];
                    if (isset($val['sum_daily_nb_uniq_visitors '])) {
                        $total['sum_daily_nb_uniq_visitors'] += $val['sum_daily_nb_uniq_visitors'];
                    }

                    $total['nb_impressions'] += $val['nb_impressions'];
                    $total['nb_interactions'] += $val['nb_interactions'];
                    //$total['interaction_rate'] += $val['interaction_rate'];
                }
            }
        }
        //重新计算合并的广告位总点击率
        if ($total['nb_impressions'] > 0) {
            $total['interaction_rate'] = round(($total['nb_interactions'] / $total['nb_impressions']) * 100, 2);
        }
        return $total;
    }

    private function _caculate_days($dataTable, $label_pre = '日') {
        $tablelist = [];
        foreach ($dataTable as $key => $r) {
            if (!empty($r)) {
                $tmp = [
                    'label'             => $key . $label_pre,
                    'day'               => $key,
                    'nb_visits'         => 0, //访问量 
                    'nb_uniq_visitors'  => 0,
                    'sum_daily_nb_uniq_visitors' => 0, //唯一访问量
                    'nb_impressions'        => 0, // 展示量
                    'nb_interactions'       => 0, // 点击量
                    'interaction_rate'      => 0, //点击率
                    'ecpm'                  => 0,
                    'cpc'                   => 0,
                ];
                //把每天的所有广告位 数据汇总
                foreach ($r as $k => $val) {
                    $tmp['nb_visits']           += $val['nb_visits'];
                    $tmp['nb_uniq_visitors']    += $val['nb_uniq_visitors'];
                    if (isset($val['sum_daily_nb_uniq_visitors'])) {
                        $tmp['sum_daily_nb_uniq_visitors'] += $val['sum_daily_nb_uniq_visitors'];
                    }
                    $tmp['nb_impressions']      += $val['nb_impressions'];
                    $tmp['nb_interactions']     += $val['nb_interactions'];
                    $tmp['interaction_rate']    += $val['interaction_rate'];
                }
                if ($tmp['nb_impressions'] > 0) {
                    $tmp['interaction_rate'] = round(($tmp['nb_interactions'] / $tmp['nb_impressions']) * 100, 2);
                }
                $tablelist[] = $tmp;
            } else {
                $tablelist[] = [
                    'label'                     => $key . $label_pre,
                    'day'                       => $key,
                    'nb_visits'                 => 0, //访问量 
                    'nb_uniq_visitors'          => 0,
                    'sum_daily_nb_uniq_visitors'=> 0, //唯一访问量
                    'nb_impressions'            => 0, // 展示量
                    'nb_interactions'           => 0, // 点击量
                    'interaction_rate'          => 0, //点击率
                    'ecpm'                      => 0,
                    'cpc'                       => 0,
                ];
            }
        }
        return $tablelist;
    }

    /**
     * 计算广告投放 的 汇总     * 
     */
    private function _caculte_by_label($format, $dataTable) {
        $tablelist = [];
        foreach ($format['filter'] as $key => $val) {
            //从 一个字符串中获取到数字 例如 adplace14name 得到14
            preg_match('/\d+/', $val, $r);
            //$r[0] = 14;

            $tablelist[$val] = [
                'id' => $r[0],
                'label' => "[{$r[0]}]" . $format['labels'][$r[0]],
                'nb_visits' => 0, //访问量 
                'nb_uniq_visitors' => 0,
                'sum_daily_nb_uniq_visitors' => 0, //唯一访问量
                'nb_impressions' => 0, // 展示量
                'nb_interactions' => 0, // 点击量
                'interaction_rate' => 0, //点击率
                'ecpm' => 0,
                'cpc' => 0,
            ];
        }
        foreach ($dataTable as $d => $rows) {
            foreach ($rows as $k => $val) {
                $tablelist[$val['label']]['nb_visits'] += $val['nb_visits'];
                $tablelist[$val['label']]['nb_uniq_visitors'] += $val['nb_uniq_visitors'];
                if (isset($val['sum_daily_nb_uniq_visitors'])) {
                    $tablelist[$val['label']]['sum_daily_nb_uniq_visitors'] += $val['sum_daily_nb_uniq_visitors'];
                }
                $tablelist[$val['label']]['nb_impressions'] += $val['nb_impressions'];
                $tablelist[$val['label']]['nb_interactions'] += $val['nb_interactions'];
                $tablelist[$val['label']]['cpc'] = 0;
                // $tablelist[$val['label']]['interaction_rate'] += $val['interaction_rate'];
            }
        }
        $return = [];
        foreach ($tablelist as $key => $val) {
            if ($val['nb_impressions'] > 0) {
                $val['interaction_rate'] = round(($val['nb_interactions'] / $val['nb_impressions']) * 100, 2);
            }

            array_push($return, $val);
        }

        return $return;
    }
    
    

}
